package com.example.demo.validator;

import com.example.demo.model.CopyrightInfo;
import com.example.demo.service.BlockchainService;
import lombok.extern.slf4j.Slf4j;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

/**
 * 版权验证器，处理版权相关的验证逻辑
 */
@Slf4j
@Component
public class CopyrightValidator {
    
    @Autowired
    private BlockchainService blockchainService;
    
    /**
     * 验证链上的版权所有权
     * @param copyrightId 版权ID
     * @param claimedOwner 声称的所有者
     * @throws IllegalArgumentException 如果验证失败
     */
    public void validateCopyrightOwnership(BigInteger copyrightId, String claimedOwner) {
        log.info("验证链上所有权: 版权ID={}, 声称所有者={}", copyrightId, claimedOwner);
        
        try {
            // 获取用户密钥对
            CryptoKeyPair userKeyPair = blockchainService.getUserKeyPair(claimedOwner);
            if (userKeyPair == null) {
                log.error("无法获取用户密钥对: {}", claimedOwner);
                throw new IllegalArgumentException("无法获取用户密钥对，请确保您的账户已导入系统");
            }
            
            // 使用用户密钥对直接从区块链获取版权信息
            CopyrightInfo chainInfo = getCopyrightFromChain(copyrightId, userKeyPair);
            
            if (chainInfo == null) {
                log.error("链上版权不存在: {}", copyrightId);
                throw new IllegalArgumentException("链上版权不存在: " + copyrightId);
            }
            
            log.info("链上所有者: {}, 声称所有者: {}", chainInfo.getOwnerAddress(), claimedOwner);
            
            // 验证所有权
            if (!chainInfo.getOwnerAddress().equalsIgnoreCase(claimedOwner)) {
                log.error("所有权验证失败: 链上所有者={}, 声称所有者={}", 
                        chainInfo.getOwnerAddress(), claimedOwner);
                throw new IllegalArgumentException("您不是该版权的链上所有者(链上所有者为: " 
                        + chainInfo.getOwnerAddress() + ")");
            }
            
            log.info("所有权验证成功: {}", claimedOwner);
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (Exception e) {
            log.error("所有权验证异常: {}", e.getMessage(), e);
            throw new IllegalArgumentException("无法验证所有权: " + e.getMessage());
        }
    }
    
    /**
     * 获取版权信息（从区块链）
     * @param copyrightId 版权ID
     * @param userKeyPair 用户密钥对
     * @return 版权信息
     */
    private CopyrightInfo getCopyrightFromChain(BigInteger copyrightId, CryptoKeyPair userKeyPair) {
        log.info("从区块链获取版权信息: ID={}, 发送方={}", copyrightId, userKeyPair.getAddress());
        
        try {
            // 创建调用参数
            List<Object> params = new ArrayList<>();
            params.add(copyrightId);
            
            // 发送合约调用
            CallResponse response = blockchainService.sendCall(
                "getCopyright", 
                params, 
                userKeyPair.getAddress()
            );
            
            // 解析结果
            String callOutput = response.getValues();
            if (callOutput == null || callOutput.isEmpty()) {
                log.warn("从区块链获取版权返回空: ID={}", copyrightId);
                return null;
            }
            
            // 解析版权信息
            String[] parts = blockchainService.parseCopyrightInfo(callOutput);
            
            // 实际格式是: [ID,hash,owner,timestamp,valid]
            if (parts.length >= 5) {
                // 清理hash(索引1)
                String hash = parts[1];
                
                // 清理owner(索引2)
                String owner = parts[2];
                
                // 处理timestamp(索引3)
                BigInteger timestamp = BigInteger.ZERO;
                try {
                    timestamp = new BigInteger(parts[3]);
                } catch (NumberFormatException e) {
                    log.warn("无法解析时间戳 '{}', 使用默认值", parts[3]);
                }
                
                // 处理isValid(索引4)
                Boolean isValid = Boolean.parseBoolean(parts[4]);
                
                log.info("解析版权: ID={}, 哈希={}, 所有者={}, 时间={}, 有效={}", 
                        copyrightId, hash, owner, timestamp, isValid);
                        
                // 创建版权信息对象
                CopyrightInfo copyright = new CopyrightInfo();
                copyright.setBlockchainId(copyrightId.toString());
                copyright.setOwnerAddress(owner);
                copyright.setImageHash(hash);
                copyright.setCreateTime(timestamp);
                copyright.setIsValid(isValid);
                
                log.info("从区块链获取版权成功: ID={}, 所有者={}", copyrightId, owner);
                return copyright;
            } else {
                log.warn("返回格式不符合预期: {}, 部分数量: {}", callOutput, parts.length);
                return null;
            }
        } catch (Exception e) {
            log.error("从区块链获取版权信息异常: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 校验版权ID是否有效
     * @param copyrightId 版权ID
     * @return 是否有效
     */
    public boolean isValidCopyrightId(BigInteger copyrightId) {
        return copyrightId != null && copyrightId.compareTo(BigInteger.ZERO) > 0;
    }
    
    /**
     * 验证地址格式是否正确
     * @param address 区块链地址
     * @return 是否是有效的地址格式
     */
    public boolean isValidAddressFormat(String address) {
        if (address == null || address.isEmpty()) {
            return false;
        }
        return address.startsWith("0x") && address.length() == 42;
    }
    
    /**
     * 检查两个地址是否可以进行转让（不能是同一地址）
     * @param fromAddress 转让方地址
     * @param toAddress 接收方地址
     * @return 是否可以转让
     */
    public boolean isValidTransferAddresses(String fromAddress, String toAddress) {
        // 检查两个地址格式是否正确
        if (!isValidAddressFormat(fromAddress) || !isValidAddressFormat(toAddress)) {
            return false;
        }
        
        // 不能转让给自己
        return !fromAddress.equalsIgnoreCase(toAddress);
    }
} 